﻿using System;
using RiskMan.Config;
using RiskMan.DataClass.Models.Quik;

namespace RiskMan.DataClass.Models.RM
{
    /// <summary>
    /// Модуль РМ(дополнение к стопа)
    /// </summary>
    public class SPrice
    {
        public Double Stopprice { get; set; }
        public Double Price { get; set; }

        public static SPrice GetStopLimitePrices ( StopListModel sl, DealModel dl, int accuraccy )
        {
            String _formate = cfg.SetFormate( accuraccy );

            SPrice result = new SPrice( );
                
                    
            if ( dl.Operation == cfg.Buy )
            {
                if ( sl.TypeRasch == cfg.ValutPrice )
                {
                    result.Stopprice = dl.Price - sl.StopOtst;

                    if ( sl.Lossless != 0 )
                    {
                        if ( dl.Price + sl.Lossless < MainWindow.StaticRiskMan._dataProvider.GetLastPrice( sl.Seccode ) )
                        {
                            result.Stopprice = dl.Price;
                        }
                    }

                    result.Price = result.Stopprice - sl.StopSprd;
                }

                if ( sl.TypeRasch == cfg.Persent )
                {
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Stopprice = Math.Round( ( dl.Price - dl.Price * sl.StopOtst / 100 ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ), 
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) ) 
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Stopprice = dl.Price - dl.Price * sl.StopOtst / 100;

                    if ( sl.Lossless != 0 )
                    {
                        if ( dl.Price + dl.Price * sl.Lossless / 100 < MainWindow.StaticRiskMan._dataProvider.GetLastPrice( sl.Seccode ) )
                        {
                            result.Stopprice = dl.Price;
                        }
                    }

                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Price = Math.Round( ( result.Stopprice - result.Stopprice * sl.StopSprd / 100 ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                       MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                     * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else 
                        result.Price = result.Stopprice - result.Stopprice * sl.StopSprd / 100;
                }
            }

            if ( dl.Operation == cfg.Sell )
            {
                if ( sl.TypeRasch == cfg.ValutPrice )
                {
                    result.Stopprice = dl.Price + sl.StopOtst;

                    if ( sl.Lossless != 0 )
                    {
                        if ( dl.Price - sl.Lossless > MainWindow.StaticRiskMan._dataProvider.GetLastPrice( sl.Seccode ) )
                        {
                            result.Stopprice = dl.Price;
                        }
                    }

                    result.Price = result.Stopprice + sl.StopSprd;
                }

                if ( sl.TypeRasch == cfg.Persent )
                {
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Stopprice = Math.Round( ( dl.Price + dl.Price * sl.StopOtst / 100 ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Stopprice = dl.Price + dl.Price * sl.StopOtst / 100;

                    if ( sl.Lossless != 0 )
                    {
                        if ( dl.Price - dl.Price * sl.Lossless / 100 > MainWindow.StaticRiskMan._dataProvider.GetLastPrice( sl.Seccode ) )
                        {
                            result.Stopprice = dl.Price;
                        }
                    }
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Price = Math.Round( ( result.Stopprice + result.Stopprice * sl.StopSprd / 100 ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                       MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                     * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Price = result.Stopprice + result.Stopprice * sl.StopSprd / 100;
                }
            }

            result.Stopprice = cfg.getDouble( _formate, result.Stopprice );
            result.Price = cfg.getDouble( _formate, result.Price );

            return result;
        }

        public static SPrice GetStopLimitePrices(StopListModel sl, double price, int accuraccy, string operation, string seccode)
        {
            String _formate = cfg.SetFormate(accuraccy);

            SPrice result = new SPrice();


            if (operation == cfg.Buy)
            {
                if (sl.TypeRasch == cfg.ValutPrice)
                {
                    result.Stopprice = price - sl.StopOtst;

                    if (sl.Lossless != 0)
                    {
                        if (price + sl.Lossless < MainWindow.StaticRiskMan._dataProvider.GetLastPrice(sl.Seccode))
                        {
                            result.Stopprice = price;
                        }
                    }

                    result.Price = result.Stopprice - sl.StopSprd;
                }

                if (sl.TypeRasch == cfg.Persent)
                {
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Stopprice = Math.Round((price - price * sl.StopOtst / 100) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Stopprice = price - price * sl.StopOtst / 100;

                    if (sl.Lossless != 0)
                    {
                        if (price + price * sl.Lossless / 100 < MainWindow.StaticRiskMan._dataProvider.GetLastPrice(sl.Seccode))
                        {
                            result.Stopprice = price;
                        }
                    }

                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Price = Math.Round((result.Stopprice - result.Stopprice * sl.StopSprd / 100) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                       MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                     * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Price = result.Stopprice - result.Stopprice * sl.StopSprd / 100;
                }
            }

            if (operation == cfg.Sell)
            {
                if (sl.TypeRasch == cfg.ValutPrice)
                {
                    result.Stopprice = price + sl.StopOtst;

                    if (sl.Lossless != 0)
                    {
                        if (price - sl.Lossless > MainWindow.StaticRiskMan._dataProvider.GetLastPrice(sl.Seccode))
                        {
                            result.Stopprice = price;
                        }
                    }

                    result.Price = result.Stopprice + sl.StopSprd;
                }

                if (sl.TypeRasch == cfg.Persent)
                {
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Stopprice = Math.Round((price + price * sl.StopOtst / 100) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Stopprice = price + price * sl.StopOtst / 100;

                    if (sl.Lossless != 0)
                    {
                        if (price - price * sl.Lossless / 100 > MainWindow.StaticRiskMan._dataProvider.GetLastPrice(sl.Seccode))
                        {
                            result.Stopprice = price;
                        }
                    }
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Price = Math.Round((result.Stopprice + result.Stopprice * sl.StopSprd / 100) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                       MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                     * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Price = result.Stopprice + result.Stopprice * sl.StopSprd / 100;
                }
            }

            result.Stopprice = cfg.getDouble(_formate, result.Stopprice);
            result.Price = cfg.getDouble(_formate, result.Price);

            return result;
        }

        public static SPrice GetTakeProfitPrices ( StopListModel sl, DealModel dl, int accuraccy )
        {
            String _formate = cfg.SetFormate( accuraccy );
            SPrice result = new SPrice( );

            if ( dl.Operation == cfg.Buy )
            {
                if ( sl.TypeRasch == cfg.ValutPrice )
                    result.Stopprice = dl.Price + sl.TakePrAc;

                if ( sl.TypeRasch == cfg.Persent )
                {
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Stopprice = Math.Round( ( dl.Price + dl.Price * sl.TakePrAc / 100 ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Stopprice = dl.Price + dl.Price * sl.TakePrAc / 100;
                }
            }
            if ( dl.Operation == cfg.Sell )
            {
                if ( sl.TypeRasch == cfg.ValutPrice )
                    result.Stopprice = dl.Price - sl.TakePrAc;

                if ( sl.TypeRasch == cfg.Persent )
                {
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Stopprice = Math.Round( ( dl.Price - dl.Price * sl.TakePrAc / 100 ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Stopprice = dl.Price - dl.Price * sl.TakePrAc / 100;
                }
            }

            result.Stopprice = cfg.getDouble( _formate, result.Stopprice );
            result.Price = cfg.getDouble( _formate, result.Price );

            return result;
        }

        public static SPrice GetTakeProfitPrices(StopListModel sl, double price, int accuraccy, string operation, string seccode)
        {
            String _formate = cfg.SetFormate(accuraccy);
            SPrice result = new SPrice();

            if (operation == cfg.Buy)
            {
                if (sl.TypeRasch == cfg.ValutPrice)
                    result.Stopprice = price + sl.TakePrAc;

                if (sl.TypeRasch == cfg.Persent)
                {
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Stopprice = Math.Round((price + price * sl.TakePrAc / 100) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Stopprice = price + price * sl.TakePrAc / 100;
                }
            }
            if (operation == cfg.Sell)
            {
                if (sl.TypeRasch == cfg.ValutPrice)
                    result.Stopprice = price - sl.TakePrAc;

                if (sl.TypeRasch == cfg.Persent)
                {
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Stopprice = Math.Round((price - price * sl.TakePrAc / 100) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Stopprice = price - price * sl.TakePrAc / 100;
                }
            }

            result.Stopprice = cfg.getDouble(_formate, result.Stopprice);
            result.Price = cfg.getDouble(_formate, result.Price);

            return result;
        }

        internal static SPrice GetLinkedOrderPrices ( StopListModel sl, DealModel dl, int accuraccy )
        {
            String _formate = cfg.SetFormate( accuraccy );
            SPrice result = new SPrice( );
            if ( dl.Operation == cfg.Buy )
            {
                if ( sl.TypeRasch == cfg.ValutPrice )
                    result.Stopprice = dl.Price + sl.TakeOtst;

                if ( sl.TypeRasch == cfg.Persent )
                {
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Stopprice = Math.Round( ( dl.Price * ( 1 + sl.TakeOtst / 100 ) ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Stopprice = dl.Price * ( 1 + sl.TakeOtst / 100 );
                }
            }
            if ( dl.Operation == cfg.Sell )
            {
                if ( sl.TypeRasch == cfg.ValutPrice )
                    result.Stopprice = dl.Price - sl.TakeOtst;

                if ( sl.TypeRasch == cfg.Persent )
                {
                    if ( MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ) > 1 )
                        result.Stopprice = Math.Round( ( dl.Price * ( 1 - sl.TakeOtst / 100 )  ) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode ),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy( dl.Seccode ) )
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice( dl.Seccode );
                    else
                        result.Stopprice = dl.Price * ( 1 - sl.TakeOtst / 100 );
                }
            }
            result.Stopprice = cfg.getDouble( _formate, result.Stopprice );
            return result;
        }

        internal static SPrice GetLinkedOrderPrices(StopListModel sl, double price, int accuraccy, string operation, string seccode)
        {
            String _formate = cfg.SetFormate(accuraccy);
            SPrice result = new SPrice();
            if (operation == cfg.Buy)
            {
                if (sl.TypeRasch == cfg.ValutPrice)
                    result.Stopprice = price + sl.TakeOtst;

                if (sl.TypeRasch == cfg.Persent)
                {
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Stopprice = Math.Round((price * (1 + sl.TakeOtst / 100)) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Stopprice = price * (1 + sl.TakeOtst / 100);
                }
            }
            if (operation == cfg.Sell)
            {
                if (sl.TypeRasch == cfg.ValutPrice)
                    result.Stopprice = price - sl.TakeOtst;

                if (sl.TypeRasch == cfg.Persent)
                {
                    if (MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode) > 1)
                        result.Stopprice = Math.Round((price * (1 - sl.TakeOtst / 100)) / MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode),
                                           MainWindow.StaticRiskMan._dataProvider.GetAccuraccy(seccode))
                                         * MainWindow.StaticRiskMan._dataProvider.GetStepPrice(seccode);
                    else
                        result.Stopprice = price * (1 - sl.TakeOtst / 100);
                }
            }
            result.Stopprice = cfg.getDouble(_formate, result.Stopprice);
            return result;
        }
    }
}